const deepClone = (obj) => {
    const cache = new Map();

    function _deepClone(obj) {
        if(typeof obj !== 'object' || obj === null) {
            return obj
        }
        if(cache.has(obj)) {
            return cache.get(obj)
        }
        const result = Array.isArray(obj) ? [] : {}
        cache.set(obj, result)
        for(const key in obj) {
            result[key] = _deepClone(obj[key])
        }
    
        return result
    } 

    return _deepClone(obj)
}

const obj = {
    arr: [1,2,3],
    a: 1,
    b: {
        c: 2
    }
}

obj.d = obj
const obj1 = deepClone(obj)


function dp(obj) {
    const cache = new Map()
    function _dp(obj) {
        if(typeof obj !== 'object' || obj === null) {
            return obj
        }
        if(cache.has(obj)) {
            return cache.get(obj)
        }
        const result = Array.isArray(obj)? [] : {}
        cache.set(obj, result)
        for(const key in obj) {
            result[key] = _dp(obj[key])
        }
        return result
    }
    return _dp(obj)
}

const obj2 = dp(obj)
console.log('obj2', obj2);


//方法2
const deepClone1 = (obj) => {
    if(typeof obj !== "object" || obj === null) {
        return obj
    }

    let copyObj;
    if(Array.isArray(obj)) {
        copyObj = []
        for (let i = 0 ; i < obj.length; i++) {
            copyObj.push(deepClone1(obj[i]))
        }        
    }else if(obj instanceof Set) {
        copyObj = new Set(...obj)
    }else if(obj instanceof Map) {
        copyObj = new Map([...obj]) 
    }else {
        copyObj = {}
        Reflect.ownKeys(obj).forEach(key => {
            copyObj[key] = deepClone1(obj[key])
        })
    }
    return copyObj
}